package top.szhome.system.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import top.szhome.framework.core.tools.util.TreeUtil;
import top.szhome.framework.starter.db.support.SimpleServiceImpl;
import top.szhome.system.convert.DeptConverter;
import top.szhome.system.dto.DeptDTO;
import top.szhome.system.entity.Dept;
import top.szhome.system.mapper.DeptMapper;
import top.szhome.system.service.DeptService;
import top.szhome.system.vo.DeptVO;

import javax.validation.constraints.NotNull;
import java.util.*;

/**
 * 部门 服务实现
 *
 * @author 唐加利
 * @date 2023/07/31
 **/
@AllArgsConstructor
@Service
@Slf4j
public class DeptServiceImpl extends SimpleServiceImpl<DeptMapper, DeptConverter, DeptDTO, Dept, DeptVO> implements DeptService {

    @Override
    public List<DeptVO> all(boolean tree) {
        List<DeptVO> depts = getBaseConvert().to(list());
        return tree ? TreeUtil.tree(depts) : depts;
    }

    @Override
    public List<DeptVO> getChildren(@NotNull Long deptId, boolean direct){
        // 只返回部门的直接下级部门
        if(direct){
            return getBaseConvert().to(list(Wrappers.lambdaQuery(Dept.class).eq(Dept::getParentId, deptId)));
        }

        List<DeptVO> all = all();
        return TreeUtil.getChildren(deptId, all);
    }

    @Override
    public List<DeptVO> getParents(@NotNull Long deptId) {
        Dept leaf = getById(deptId);
        Long parentId = leaf.getParentId();

        // 没有上级节点
        if(parentId == null || parentId == 0){
            return Collections.EMPTY_LIST;
        }

        List<Dept> result = new ArrayList<>();

        // 找出所有父节点
        List<Dept> list = list();
        Map<Long, Dept> map = new HashMap<>(list.size());

        out: for(Dept dept : list) {
            map.put(dept.getId(), dept);
            while ((dept = map.get(parentId)) != null) {
                result.add(dept);
                parentId = dept.getParentId();

                if(parentId == null || parentId == 0){
                    break out;
                }
            }
        }

        return getBaseConvert().to(result);
    }
}
